#include "VEnginePCH.h"
#include "VRenderObjectGLES.h"
#include "VRenderOGL.h"

//////////////////////////////////////////////////////////////////////////
//	VertexBuffer
//////////////////////////////////////////////////////////////////////////
VVertexBufferOGL::~VVertexBufferOGL()
{
	if (m_glVBO)
	{
		glDeleteBuffers(1, &m_glVBO);
	}
	if (m_ShadowBuffer)
	{
		VFree(m_ShadowBuffer);
	}
}

BOOL VVertexBufferOGL::Init()
{
	glGenBuffers(1, &m_glVBO);
	if (!m_glVBO)
	{
		VLOG("VVertexBufferOGL::Init create gles vbo failed!");
		return FALSE;
	}
	glBindBuffer(GL_ARRAY_BUFFER, m_glVBO);
	GLenum Usage = m_Dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
	glBufferData(GL_ARRAY_BUFFER, m_Size, NULL, Usage);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	((VRenderOGL*)VRI)->InvalidHWVertexBuffer();	
	return TRUE;
}

void* VVertexBufferOGL::Lock(UINT Offset, UINT Size, UINT LockFlags)
{
	VASSERT(m_glVBO);
	if (!m_ShadowBuffer)
	{
		m_ShadowBuffer = (BYTE*)VMalloc(m_Size);
		if (m_ShadowBuffer == NULL)
		{
			return NULL;
		}
	}
	return m_ShadowBuffer + Offset; 
}
void VVertexBufferOGL::Unlock()
{
	VASSERT(m_glVBO);
	if (m_ShadowBuffer)
	{
		glBindBuffer(GL_ARRAY_BUFFER, m_glVBO);
		GLenum Usage = m_Dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
		glBufferData(GL_ARRAY_BUFFER, m_Size, m_ShadowBuffer, Usage);
		if (!m_Dynamic)
		{
			VFree(m_ShadowBuffer);
			m_ShadowBuffer = NULL;
		}
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		((VRenderOGL*)VRI)->InvalidHWVertexBuffer();
	}
}

//////////////////////////////////////////////////////////////////////////
//	IndexBuffer
//////////////////////////////////////////////////////////////////////////
VIndexBufferOGL::~VIndexBufferOGL()
{
	if (m_glVBO)
	{
		glDeleteBuffers(1, &m_glVBO);
	}
	if (m_ShadowBuffer)
	{
		VFree(m_ShadowBuffer);
	}
}

BOOL VIndexBufferOGL::Init()
{
	glGenBuffers(1, &m_glVBO);
	if (!m_glVBO)
	{
		VLOG("VIndexBufferOGL::Init create gles vbo failed!");
		return FALSE;
	}
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_glVBO);
	GLenum Usage = m_Dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Size, NULL, Usage);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	((VRenderOGL*)VRI)->InvalidHWIndexBuffer();
	return TRUE;
}

void* VIndexBufferOGL::Lock(UINT Offset, UINT Size, UINT LockFlags)
{
	VASSERT(m_glVBO);
	if (!m_ShadowBuffer)
	{
		m_ShadowBuffer = (BYTE*)VMalloc(m_Size);
		if (m_ShadowBuffer == NULL)
		{
			return NULL;
		}
	}
	return m_ShadowBuffer + Offset; 
}
void VIndexBufferOGL::Unlock()
{
	VASSERT(m_glVBO);
	if (m_ShadowBuffer)
	{
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_glVBO);
		GLenum Usage = m_Dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW;
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Size, m_ShadowBuffer, Usage);
		if (!m_Dynamic)
		{
			VFree(m_ShadowBuffer);
			m_ShadowBuffer = NULL;
		}
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		((VRenderOGL*)VRI)->InvalidHWIndexBuffer();
	}

}
//////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////
VTextureOGL::~VTextureOGL()
{
	VASSERT(VRI);
	if (m_ResourceName)
	{
		((VRenderOGL*)VRI)->UnregisterTexture(m_ResourceName);
	}
	
	if (m_glID)
	{
		glDeleteTextures(1, &m_glID);
	}
}

void VTextureOGL::DeleteThis()
{
	delete this;
}

BOOL VTextureOGL::UpdateSurface(int X, int Y, int Width, int Height,const void* SrcData)
{
	VASSERT(m_glID);
	GLenum glFormat = VRenderOGL::GetGLInternalForamt(m_Format);
	GLenum glPixelType = VRenderOGL::GetGLPixelType(m_Format);
	if (glFormat == 0 || glPixelType == 0)
	{
		return FALSE;
	}
	glBindTexture(GL_TEXTURE_2D, m_glID);
	glTexSubImage2D(GL_TEXTURE_2D, 0, X, Y, Width, Height, glFormat, glPixelType, SrcData);
	return TRUE;
}